package com.woniu.adminservice.realm;

import com.woniu.adminservice.dao.AccountDao;
import com.woniu.adminservice.dao.MenusDao;
import com.woniu.adminservice.dao.RolesDao;
import com.woniu.adminservice.entity.Account;
import com.woniu.adminservice.entity.Roles;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * shiro自定义域
 */
public class CustomRealm extends AuthorizingRealm {

    @Resource
    private AccountDao accountDao;

    @Resource
    private RolesDao rolesDao;

    @Resource
    private MenusDao menusDao;


    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取登录认证成功的主体
        Account account = (Account) principals.getPrimaryPrincipal();
        //根据认证的id查询所有角色
        List<Roles> roles = rolesDao.selectRolesByUserId(account.getUserid());
        List roleId = new ArrayList();
        for (Roles role : roles) {
            roleId.add(role.getId());
        }
        //根据角色查询所拥有的权限
        List<String> prems = menusDao.selectPermsByRoles(roleId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(prems);
        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取主体
        String userName = (String) token.getPrincipal();
        Account account = accountDao.selectByUseName(userName);
        if (account==null){
            throw new UnknownAccountException("账号不存在");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account,account.getPassword(),super.getName());
        //设置盐值
        info.setCredentialsSalt(ByteSource.Util.bytes(account.getSalt()));
        return info;
    }
}
